package cn.basic.dao.impl;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.basic.dao.BasicDao;
import cn.util.PageBean;
public abstract class BasicDaoImpl extends HibernateDaoSupport implements BasicDao {
Logger logger = Logger.getLogger(BasicDaoImpl.class);
	
	public Integer deleteObj(Object object) {
		this.getHibernateTemplate().delete(object);
		return 1;
	}

	@SuppressWarnings("unchecked")
	public List<Object> findListByCondition(String hql,Map<Serializable, Serializable> condition) {
		Query query = this.getSession().createQuery(hql);
		query = this.addCondition(query, condition);
		if(condition!=null){
			Object pageNow =  condition.get("$pageNow");
			Object pageSize = condition.get("$pageSize");
			if(pageNow!=null&&pageSize!=null&&pageNow instanceof Integer && pageSize instanceof Integer){
				int pNow = (Integer) pageNow;
				int pSize = (Integer) pageSize;
				if(pNow>0&&pSize>0){
					query.setFirstResult((pNow-1)*pSize).setMaxResults(pSize);
				}
			}
		}
		return query.list();
	}

	public Object findObjByCondition(String hql,Map<Serializable, Serializable> condition) {
		Query query = this.getSession().createQuery(hql);
		query = this.addCondition(query, condition);
		Object result  = null;
		try {
			 result = query.uniqueResult();
		} catch (Exception e) {
			result = null;
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public Object findObjById(Class classes, Serializable id) {
		return this.getSession().get(classes, id);
	}

	public Object getListCount(String hql,Map<Serializable, Serializable> condition) {
		Query query = this.getSession().createQuery(hql);
		this.addCondition(query, condition);
		Object result = query.uniqueResult();
		return result==null?0:result;
	}

	public Integer saveObj(Object object) {
		this.getHibernateTemplate().save(object);
		return 1;
	}

	public Integer updateObj(Object object) {
		this.getHibernateTemplate().update(object);
		return 1;
	}

	public Integer batchInsert(Collection<Object> collections) {
		if(null==collections||collections.size()<1){
			return 0;
		}
		int size = collections.size();
		Session session = this.getSession();
		Transaction tx = session.beginTransaction();
		Object[] objects = collections.toArray();
		for (int i = 0; i < size; i++) {
			session.save(objects[i]);
			if(i%200==0){
				tx.commit();
				tx = session.beginTransaction();
			}
		}
		tx.commit();
		return size;
	}
	
	public Integer deleteObjByCondition(final String sql,final Map<Serializable, Serializable> condition) {
		return this.updateObjsByCondition(sql, condition);
	}
	
	public Integer updateObjsByCondition(final String sql,final Map<Serializable, Serializable> condition) {
		return this.getHibernateTemplate().execute(
				new HibernateCallback<Integer>() {
					@SuppressWarnings("deprecation")
					public Integer doInHibernate(Session session)throws HibernateException, SQLException {
						
						if(null==sql||("".equals(sql.trim()))){
							return 0;
						}
						
						Connection conn = session.connection();
						PreparedStatement pst = conn.prepareStatement(sql);
						if (condition != null && condition.size() > 0) {
							for (Serializable key : condition.keySet()) {
								pst.setObject((Integer) key, condition.get(key));
							}
						}
						
						if(pst!=null){
							return pst.executeUpdate();
						}else {
							return 0;
						}
					}
				});
	}
	
	/**
	 * 取分页数据
	 * @param hql                 hql 语句   如：from UserBean    userbean  为javabean
	 * @param condition           查询条件    要以“_”开头
	 * @param pageNow             当前页
	 * @param pageSize            每页显示多少个
	 * @return
	 */
	public PageBean fetchPage(String hql,Map<Serializable, Serializable> condition,Integer pageNow,Integer pageSize){
		PageBean pageBean = new PageBean();
		Object sumCount  = this.getListCount("select count(*) " + hql, condition);
		if(condition!=null){
			condition.put("$pageNow", pageNow);
			condition.put("$pageSize", pageSize);
		}
		List<Object> pageItems = this.findListByCondition(hql + " order by id desc", condition);
		
		pageBean.setPageItems(pageItems);
		pageBean.setSumCount(((Long)sumCount).intValue());
		pageBean.setPageNow(pageNow);
		pageBean.setPageSize(pageSize);
		return pageBean;
	}
	
	/**
	 * @param query
	 * @param condition
	 * @return
	 */
	private Query addCondition(Query query,Map<Serializable, Serializable> condition){
		if(condition!=null&&query!=null){
			for (Serializable key : condition.keySet()) {
				if(key.toString().startsWith("_")){          //以 “_”开始的是查询条件
					query.setParameter((String)key, condition.get(key));
				}
			}
		}
		return query;
	}

}
